/**
 *
 */
package com.bsoft.gol.hcb.dao.evaluation;

import com.bsoft.gol.hcb.utils.CommonUtils;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.spring.boot.annotation.SsdevDao;
import ctd.util.annotation.RpcService;
import org.atag.dao.action.QoHibernateStatelessResultAction;
import org.atag.dao.util.BaseDaoImpl;
import org.atag.dao.util.CustomAliasToEntityMapResultTransformer;
import org.hibernate.SQLQuery;
import org.hibernate.StatelessSession;
import pcn.bean.consultation.BaseEvaluationRecordList;
import pcn.bean.sign.EvaluationRecordQo;
import pcn.sign.BaseEvaluationRecord;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @since 2017-05-03 04:17:29
 */
@SsdevDao(serviceId = "baseEvaluationDaoService")
public abstract class BaseEvaluationRecordDAO extends BaseDaoImpl<BaseEvaluationRecord> {

	public BaseEvaluationRecordDAO() {
		this.setKeyField("id");
	}

	@DAOMethod(sql = "from BaseEvaluationRecord where id=:id")
	public abstract BaseEvaluationRecord getBaseEvaluationRecordById(@DAOParam("id") int id);

	@DAOMethod(sql = "from BaseEvaluationRecord where  defineId=:defineId and  businessType=:businessType and businessId=:businessId")
	public abstract BaseEvaluationRecord getByDefineIdAndBusinessId(@DAOParam("defineId") Integer defineId, @DAOParam("businessType") String businessType, @DAOParam("businessId") String businessId);

	@DAOMethod(sql = "from BaseEvaluationRecord")
	public abstract List<BaseEvaluationRecord> findBaseEvaluationRecords();

	@DAOMethod(sql = "select * from BaseEvaluationRecord where userId=:userId and businessId=:businessId and " +
			"businessType=:businessType")
	public abstract List<BaseEvaluationRecord> getRecordByUserIdAndBusinessIdAndType(@DAOParam("userId") String userId
			, @DAOParam("businessId") String businessId, @DAOParam("businessType") String businessType);

	@DAOMethod(sql = "select count(1) from BaseEvaluationRecord where userId=:userId and businessId=:businessId")
	public abstract Long getCountByUserIdAndBusinessId(@DAOParam("userId") String userId,
													   @DAOParam("businessId") String businessId);

	@DAOMethod(sql = "select count(1) from BaseEvaluationRecord where objectId=:objectId and verifyState='1' ")
	public abstract Long getPatientEvaluateCount(@DAOParam("objectId") String objectId );

	@DAOMethod(sql = "select count(1) from BaseEvaluationRecord where userId=:userId and businessId=:businessId and " +
			"businessType=:businessType")
	public abstract Long getCountByUserIdAndBusinessIdAndType(@DAOParam("userId") String userId, @DAOParam("businessId"
	) String businessId, @DAOParam("businessType") String businessType);

	@RpcService
	@DAOMethod(sql = "from BaseEvaluationRecord where businessId=:businessId")
	public abstract List<BaseEvaluationRecord> findBaseEvaluationRecordsByExeId(@DAOParam("businessId") String businessId);

	@DAOMethod(sql = "from BaseEvaluationRecord where businessType=:businessType and businessId=:businessId  and orgId=:orgId ")
	public abstract List<BaseEvaluationRecord> findBaseEvaluationRecordsByBusinessId(@DAOParam("businessType") String businessType, @DAOParam("businessId") String businessId, @DAOParam("orgId") String orgId);

	@RpcService
	@DAOMethod(sql = "from BaseEvaluationRecord where businessType in:businessTypeList and verifyTime>=:beginDate  " +
			"and" +
			" verifyTime<:endDate and verifyState='1'")
	public abstract List<BaseEvaluationRecord> findBaseEvaluationRecordsByAddTime(@DAOParam("businessTypeList") List<String> businessTypeList, @DAOParam("beginDate") Date beginDate, @DAOParam("endDate") Date endDate);

	public List<BaseEvaluationRecordList> queryEvaluationRecordLists(final pcn.bean.consultation.EvaluationRecordQo qo) {
		Map<String, Object> params = new HashMap<>();

		StringBuffer hsql = new StringBuffer();
		hsql.append("select a.id as recordId, a.org_name, a.person_name, a.phone_no,a.object_name as doctorName,a.verify_state,a.label_name," +
				" a.evaluation_type,a.business_type,a.add_time from base_evaluation_record a where 1=1 ");
		if (CommonUtils.isNotEmpty(qo.getDoctorName())) {
			hsql.append(" and a.object_name like :objectName");
			params.put("objectName", "%" + qo.getDoctorName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getPersonName())) {
			hsql.append(" and a.person_name like :personName");
			params.put("personName", "%" + qo.getPersonName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getEvaluationType())) {
			hsql.append(" and a.evaluation_type = :evaluationType");
			params.put("evaluationType", qo.getEvaluationType());
		}
		if (CommonUtils.isNotEmpty(qo.getBusinessType())) {
			hsql.append(" and a.business_type =:businessType ");
			params.put("businessType", qo.getBusinessType());
		}
		if (CommonUtils.isNotEmpty(qo.getVerifyState())) {
			hsql.append(" and a.verify_state = :verifyState");
			params.put("verifyState", qo.getVerifyState());
		}
		if (CommonUtils.isNotEmpty(qo.getPhoneNo())) {
			hsql.append(" and a.phone_no = :phoneNo");
			params.put("phoneNo", qo.getPhoneNo());
		}
		if (CommonUtils.isNotEmpty(qo.getOrgName())) {
			hsql.append(" and a.org_name like :orgName");
			params.put("orgName", "%" + qo.getOrgName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getDefineIdList())) {
			hsql.append(" and a.define_id in(:defineIdList) ");
			params.put("defineIdList", qo.getDefineIdList());
		}
		hsql.append(" order by a.add_time desc");

		return super.findListBySql(hsql.toString(), params, BaseEvaluationRecordList.class, qo.getPageNo(), qo.getPageSize());
	}

	public Long getEvaluationRecordCount(final pcn.bean.consultation.EvaluationRecordQo qo) {
		Map<String, Object> params = new HashMap<>();

		StringBuffer hsql = new StringBuffer();
		hsql.append("select count(1) from base_evaluation_record a where 1=1 ");
		if (CommonUtils.isNotEmpty(qo.getDoctorName())) {
			hsql.append(" and a.object_name like :objectName");
			params.put("objectName", "%" + qo.getDoctorName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getPersonName())) {
			hsql.append(" and a.person_name like :personName");
			params.put("personName", "%" + qo.getPersonName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getEvaluationType())) {
			hsql.append(" and a.evaluation_type = :evaluationType");
			params.put("evaluationType", qo.getEvaluationType());
		}
		if (CommonUtils.isNotEmpty(qo.getBusinessType())) {
			hsql.append(" and a.business_type =:businessType ");
			params.put("businessType", qo.getBusinessType());
		}
		if (CommonUtils.isNotEmpty(qo.getVerifyState())) {
			hsql.append(" and a.verify_state = :verifyState");
			params.put("verifyState", qo.getVerifyState());
		}
		if (CommonUtils.isNotEmpty(qo.getPhoneNo())) {
			hsql.append(" and a.phone_no = :phoneNo");
			params.put("phoneNo", qo.getPhoneNo());
		}
		if (CommonUtils.isNotEmpty(qo.getOrgName())) {
			hsql.append(" and a.org_name like :orgName");
			params.put("orgName", "%" + qo.getOrgName() + "%");
		}
		if (CommonUtils.isNotEmpty(qo.getDefineIdList())) {
			hsql.append(" and a.define_id in(:defineIdList) ");
			params.put("defineIdList", qo.getDefineIdList());
		}
		return super.findForLongBySql(hsql.toString(), params);
	}

	public List<BaseEvaluationRecord> queryEvaluationRecordList(EvaluationRecordQo qo) {
		QoHibernateStatelessResultAction<BaseEvaluationRecord, EvaluationRecordQo> action = new QoHibernateStatelessResultAction(false, qo, BaseEvaluationRecord.class);
		action.setSql("select * from base_evaluation_record where 1=1");
		action.addCondition("and user_id =:userId");
		action.addCondition("and business_type =:businessType");
		action.addCondition("and define_id in(:defineIdList)");
		action.addCondition("and object_name like :%exeUserName%");

		action.addSql(" order by add_time desc");

		HibernateSessionTemplate.instance().execute(action);
		return action.getResultList();
	}

	@RpcService
	@DAOMethod(sql = " from BaseEvaluationRecord where orgId=:orgId and addTime BETWEEN :startDate and :endDate limit :indx , :ofset")
	public abstract List<BaseEvaluationRecord> queryByOrgIdAndCreateTime(@DAOParam("orgId") String orgId,
																		 @DAOParam("startDate") Date startDate,
																		 @DAOParam("endDate") Date endDate,
																		 @DAOParam("indx") int indx,
																		 @DAOParam("ofset") int ofset);

	@RpcService
	@DAOMethod(sql = "select count(1) from BaseEvaluationRecord where orgId=:orgId and addTime BETWEEN :startDate and :endDate")
	public abstract long getCountByOrgIdAndCreateTime(@DAOParam("orgId") String orgId,
																		 @DAOParam("startDate") Date startDate,
																		 @DAOParam("endDate") Date endDate);


	/**
	 * @description: 查询对象评价平均值
	 * @author: chenJij@bsoft.com.cn
	 * @date: 2023/6/2 15:50
	 * @param: objectId
	 * @param: orgId
	 * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
	 */
	@RpcService
	public Double getEvaluationAvgById(final String objectId, final String orgId) {
		HibernateStatelessResultAction<Double> action = new AbstractHibernateStatelessResultAction<Double>() {
			@Override
			public void execute(StatelessSession ss) throws Exception {
				String hsql = "SELECT " +
						" avg( ir.LEVEL ) AS avgLevel, " +
						" s.object_id as objectId " +
						"FROM " +
						" base_evaluation_record s, " +
						" base_evaluation_itemrecord ir  " +
						"WHERE " +
						" ir.record_id = s.id  " +
						" AND s.object_id =:objectId  " +
						" AND s.org_id =:orgId  " +
						"GROUP BY " +
						" s.object_id ";
				SQLQuery query = ss.createSQLQuery(hsql);
				query.setResultTransformer(CustomAliasToEntityMapResultTransformer.INSTANCE);
				query.setParameter("objectId", objectId);
				query.setParameter("orgId", orgId);
				List<Map<String, Object>> list = (List<Map<String, Object>>) query.list();
				if(CommonUtils.isNotEmpty(list)){
					for (Map<String, Object> objectMap : list) {
						Object avgLevel = objectMap.get("avgLevel");
						if(null == avgLevel){
							setResult(5.0);
						}else {
							BigDecimal bigDecimal = new BigDecimal(String.valueOf(avgLevel)).setScale(2,RoundingMode.HALF_UP);
							setResult(bigDecimal.doubleValue());
						}
					}
				}
			}
		};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}

	/**
	 * @description: 查询对象评价记录
	 * @author: chenJij@bsoft.com.cn
	 * @date: 2023/6/2 15:50
	 * @param: objectId
	 * @param: orgId
	 * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
	 */
	@RpcService
	@DAOMethod(sql = "from BaseEvaluationRecord where businessType=:businessType and businessId in:businessIdList  and orgId=:orgId ")
	public abstract List<BaseEvaluationRecord> queryBaseEvaluationRecordList(@DAOParam("businessType") String businessType, @DAOParam("businessIdList") List<String> businessIdList, @DAOParam("orgId") String orgId);

}